package com.bl.andr.utillib;

import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.os.Build;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

import java.lang.reflect.Field;

/**
 * DESC:屏幕工具类
 * TIME:2019-06-24
 */
public class ScreenUtil {

    private ScreenUtil() {
    }


///////////////////////////////////////////////////////////////////////////
// dp sp px
///////////////////////////////////////////////////////////////////////////


    public static DisplayMetrics getDM(Context context) {
        return context.getResources().getDisplayMetrics();
    }


    public static float getDensity(Context context) {
        return getDM(context).density;
    }

    public static float getScaledDensity(Context context) {
        return getDM(context).scaledDensity;
    }


    /**
     * 将px值转换为dip或dp值，保证尺寸大小不变
     *
     * @param pxValue （DisplayMetrics类中属性density）
     */
    public static float px2dp(Context context, float pxValue) {
        return pxValue / getDensity(context) + 0.5f;
    }

    /**
     * 将dip或dp值转换为px值，保证尺寸大小不变
     *
     * @param dipValue （DisplayMetrics类中属性density）
     */

    public static float dp2px(Context context, float dipValue) {
        return dipValue * getDensity(context) + 0.5f;
    }


    /**
     * 将px值转换为sp值，保证文字大小不变
     *
     * @param pxValue （DisplayMetrics类中属性scaledDensity）
     */

    public static float px2sp(Context context, float pxValue) {
        return pxValue / getScaledDensity(context) + 0.5f;
    }

    /**
     * 将sp值转换为px值，保证文字大小不变
     *
     * @param spValue （DisplayMetrics类中属性scaledDensity）
     */

    public static float sp2px(Context context, float spValue) {
        return spValue * getScaledDensity(context) + 0.5f;
    }

    /**
     * @param value 数值
     * @param unit  单位
     * @return
     */
    private static float unit(Context context, float value, int unit) {
        return TypedValue.applyDimension(unit, value, getDM(context));
    }

    public static float dpUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_DIP);
    }

    public static float pxUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_PX);
    }

    public static float spUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_SP);
    }


    /**
     * dp2px
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getApplicationContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }


///////////////////////////////////////////////////////////////////////////
// 屏幕宽高
///////////////////////////////////////////////////////////////////////////


    public static int getScreenW(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    public static int getScreenH(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }


    /**
     * 获取屏幕的宽度px
     *
     * @param context 上下文
     * @return 屏幕宽px
     */
    public static int getScreenWidth(Context context) {
        //  WindowManager windowManager = ((Activity) context).getWindowManager()
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.widthPixels;
    }

    /**
     * 获取屏幕的高度px
     *
     * @param context 上下文
     * @return 屏幕高px
     */
    public static int getScreenHeight(Context context) {
        //     //  WindowManager windowManager = ((Activity) context).getWindowManager()
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.heightPixels;
    }

    /**
     * 获取屏幕的真实高低 即包含底部虚拟导航栏
     *
     * @param context
     * @return
     */
    public static int getScreenRealHeight(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(dm);
        } else {
            display.getMetrics(dm);
        }
        return dm.heightPixels;
    }

    /**
     * 横屏时
     *
     * @param context
     * @return
     */
    public static int getScreenRealWidth(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(dm);
        } else {
            display.getMetrics(dm);
        }
        return dm.widthPixels;
    }


    public static int getScreenHeightWithoutStatusBarH(Context context) {
        DisplayMetrics localDisplayMetrics = new DisplayMetrics();
        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);
        return localDisplayMetrics.heightPixels - getStatusBarHeightByReflect(context);
    }


///////////////////////////////////////////////////////////////////////////
//  状态栏
///////////////////////////////////////////////////////////////////////////

    /**
     * 设置透明状态栏(api大于19方可使用)
     * <p>可在Activity的onCreat()中调用</p>
     * <p>需在顶部控件布局中加入以下属性让内容出现在状态栏之下</p>
     * <p>android:clipToPadding="true"</p>
     * <p>android:fitsSystemWindows="true"</p>
     *
     * @param activity activity
     */
    public static void setTransparentStatusBar(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 隐藏状态栏
     * <p>也就是设置全屏，一定要在setContentView之前调用，否则报错</p>
     * <p>此方法Activity可以继承AppCompatActivity</p>
     * <p>启动的时候状态栏会显示一下再隐藏，比如QQ的欢迎界面</p>
     * <p>在配置文件中Activity加属性android:theme="@android:style/Theme.NoTitleBar.Fullscreen"</p>
     * <p>如加了以上配置Activity不能继承AppCompatActivity，会报错</p>
     *
     * @param activity activity
     */
    public static void hideStatusBar(Activity activity) {
        activity.requestWindowFeature(Window.FEATURE_NO_TITLE);
        activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }

    /**
     * 获取状态栏高度
     *
     * @param context 上下文
     * @return 状态栏高度
     */
    public static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources()
                .getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

    public static int getStatusBarHeightByReflect(Context context) {
        int statusBarHeight = 0;
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object o = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = (Integer) field.get(o);
            statusBarHeight = context.getApplicationContext().getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight == 0 ? dip2px(context, 25) : statusBarHeight;
    }


    public static int getStatusBarHeight2(Context context) {
        int statusBarHeight = 0;
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object o = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = (Integer) field.get(o);
            statusBarHeight = context.getApplicationContext().getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight == 0 ? (int)dp2px(context, 25) : statusBarHeight;
    }


    /**
     * 判断状态栏是否存在
     *
     * @param activity activity
     * @return {@code true}: 存在<br>{@code false}: 不存在
     */
    public static boolean isStatusBarExists(Activity activity) {
        WindowManager.LayoutParams params = activity.getWindow().getAttributes();
        return (params.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) !=
                WindowManager.LayoutParams.FLAG_FULLSCREEN;
    }

///////////////////////////////////////////////////////////////////////////
//  ActionBar
///////////////////////////////////////////////////////////////////////////

    /**
     * 获取ActionBar高度
     *
     * @param activity activity
     * @return ActionBar高度
     */
    public static int getActionBarHeight(Activity activity) {
        TypedValue tv = new TypedValue();
        if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
            return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
        }
        return 0;
    }

///////////////////////////////////////////////////////////////////////////
// 通知栏
///////////////////////////////////////////////////////////////////////////

//    /**
//     * 显示通知栏
//     * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
//     *
//     * @param context        上下文
//     * @param isSettingPanel {@code true}: 打开设置<br>{@code false}: 打开通知
//     */
//    public static void showNotificationBar(Context context, boolean isSettingPanel) {
//        String methodName = (Build.VERSION.SDK_INT <= 16) ? "expand"
//                : (isSettingPanel ? "expandSettingsPanel" : "expandNotificationsPanel");
//        invokePanels(context, methodName);
//    }
//
//    /**
//     * 隐藏通知栏
//     * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
//     *
//     * @param context 上下文
//     */
//    public static void hideNotificationBar(Context context) {
//        String methodName = (Build.VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels";
//        invokePanels(context, methodName);
//    }
//
//    /**
//     * 反射唤醒通知栏
//     *
//     * @param context    上下文
//     * @param methodName 方法名
//     */
//    private static void invokePanels(Context context, String methodName) {
//        try {
//            Object service = context.getSystemService("statusbar");
//            Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
//            Method expand = statusBarManager.getMethod(methodName);
//            expand.invoke(service);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }


///////////////////////////////////////////////////////////////////////////
// 屏幕截图，常用
///////////////////////////////////////////////////////////////////////////    

    /**
     * 获取当前屏幕截图，包含状态栏
     *
     * @param activity activity
     * @return Bitmap
     */
    public static Bitmap captureWithStatusBar(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
        view.destroyDrawingCache();
        return bp;
    }

    /**
     * 获取当前屏幕截图，不包含状态栏
     * <p>需要用到上面获取状态栏高度getStatusBarHeight的方法</p>
     *
     * @param activity activity
     * @return Bitmap
     */
    public static Bitmap captureWithoutStatusBar(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        int statusBarHeight = getStatusBarHeight(activity);
        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
        view.destroyDrawingCache();
        return bp;
    }


///////////////////////////////////////////////////////////////////////////
// 横竖屏，锁屏
///////////////////////////////////////////////////////////////////////////

    /**
     * 判断是否锁屏
     *
     * @param context 上下文
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean isScreenLock(Context context) {
        KeyguardManager km = (KeyguardManager) context
                .getSystemService(Context.KEYGUARD_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            return km.isKeyguardLocked();
        else
            return km.inKeyguardRestrictedInputMode();
    }


    /**
     * Return whether screen is landscape.
     *
     * @return {@code true}: yes<br>{@code false}: no
     */

    public static boolean isLandscape(Activity activity) {

        return activity.getResources().getConfiguration().orientation
                == Configuration.ORIENTATION_LANDSCAPE;

    }


    /**
     * Return whether screen is portrait.
     *
     * @return {@code true}: yes<br>{@code false}: no
     */
    public static boolean isPortrait(Activity activity) {

        return activity.getResources().getConfiguration().orientation

                == Configuration.ORIENTATION_PORTRAIT;
    }

    /**
     * 设置屏幕为横屏
     * <p>还有一种就是在Activity中加属性android:screenOrientation="landscape"</p>
     * <p>不设置Activity的android:configChanges时，切屏会重新调用各个生命周期，切横屏时会执行一次，切竖屏时会执行两次</p>
     * <p>设置Activity的android:configChanges="orientation"时，切屏还是会重新调用各个生命周期，切横、竖屏时只会执行一次</p>
     * <p>设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"（4.0以上必须带最后一个参数）时
     * 切屏不会重新调用各个生命周期，只会执行onConfigurationChanged方法</p>
     *
     * @param activity activity
     */
    public static void setLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

///////////////////////////////////////////////////////////////////////////
// 适配
//    https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA
///////////////////////////////////////////////////////////////////////////

//    private static float scaledDensity;
//    private static float density;
//    private static float densityDpi;
//
//
//    /**
//     * Reference from: https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA
//     * 我知道你的意思 依mdpi为例，设计图标的多少xml就写多少 ，实际就是1：1的意思，
//     */
//
//    private static void adaptScreen(final Activity activity,
//
//                                    final float sizeInDp,
//
//                                    final boolean isVerticalSlide) {
//        final DisplayMetrics appDm = BaseApplication.getInstance().getResources().getDisplayMetrics();
//        //每次创建Activity时，这里的值都会是初始值
//        density = appDm.density;
//        scaledDensity = appDm.scaledDensity;
//        densityDpi = appDm.densityDpi;
//
//
//        final DisplayMetrics sysDm = Resources.getSystem().getDisplayMetrics();
//        final DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
//
//        if (isVerticalSlide) {
//
//            activityDm.density = activityDm.widthPixels / sizeInDp;
//
//        } else {
//
//            activityDm.density = activityDm.heightPixels / sizeInDp;
//
//        }
//        Log.d("ScreenUtil", "density=" + density + " appDm.density=" + appDm.density + " appDm.density==" + sysDm.density + " activityDm.density= " + activityDm.density);
//
//        //当activity的density变化时，application的density也会跟着变化，所以这里要使用前面保存的值
//        // activityDm.scaledDensity = activityDm.density * (scaledDensity / density);
//        activityDm.scaledDensity = activityDm.density * (sysDm.scaledDensity / sysDm.density);
//        activityDm.densityDpi = (int) (160 * activityDm.density);
//
//        appDm.density = activityDm.density;
//        appDm.scaledDensity = activityDm.scaledDensity;
//        appDm.densityDpi = activityDm.densityDpi;
//    }
//
//
//
//    /**
//     * Adapt the screen for vertical slide.
//     *
//     * @param designWidthInDp The size of design diagram's width, in dp,
//     *                        <p>
//     *                        e.g. the design diagram width is 720px, in XHDPI device,
//     *                        <p>
//     *                        the designWidthInDp = 720 / 2.
//     */
//
//    public static void adaptScreenPortrait(final Activity activity,
//
//                                           final int designWidthInDp) {
//
//        adaptScreen(activity, designWidthInDp, true);
//
//    }
//
//
//    /**
//     * Adapt the screen for horizontal slide.
//     *
//     * @param designHeightInDp The size of design diagram's height, in dp,
//     *                         <p>
//     *                         e.g. the design diagram height is 1080px, in XXHDPI device,
//     *                         <p>
//     *                         the designHeightInDp = 1080 / 3.
//     */
//
//    public static void adaptScreenLandscape(final Activity activity,
//
//                                            final int designHeightInDp) {
//
//        adaptScreen(activity, designHeightInDp, false);
//
//    }
//
//
//    /**
//     * Cancel adapt the screen.
//     *
//     * @param activity The activity.
//     */
//
//    public static void cancelAdaptScreen(final Activity activity) {
//
//        final DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
//
//        activityDm.density = density;
//        activityDm.scaledDensity = scaledDensity;
//        activityDm.densityDpi = (int) densityDpi;
//
//    }


}
